'''
Contains the BlueCarpetClaim class, which is used to create a new HP Blue Carpet claim.
'''
import PySimpleGUI as sg
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from warranty_manager.claim.claim import Claim


class BlueCarpetClaim(Claim):
    '''Creates a new HP Blue Carpet claim.'''
    def __go_to_new_claim_page(self):
        self._browser.get('https://partner.hp.com/group/upp-na/esm/-/link/37603')
        self._accept_cookies()
        # To click the link to create a new claim
        self._browser.get('https://usa.hpbluecarpet.com/application/default.aspx?PageID=3')

    def __fill_out_claim_setup(self):
        '''Completes all the fields in Step 1 of the new claim.'''
        # Choose the correct claim type
        claim_type_select = Select( self._browser.find_element_by_id('ctl04_ddlPartnerClaimTypes') )
        claim_type_select.select_by_visible_text('Sales Claim – Standard Digital')

        # Fill in the invoice date
        self._wait.until(
            EC.presence_of_element_located( (By.ID, 'ctl04_radInvoiceDate_dateInput') )
        ).send_keys( self._info.get('invoice date').strftime('%m/%d/%Y') )

        # Fill in the purchase order number
        self._wait.until(
            EC.presence_of_element_located( (By.ID, 'ctl04_InvoiceNumber') )
        ).send_keys( self._info.get('po number') )

        # Fill in the invoice number
        self._wait.until(
            EC.presence_of_element_located( (By.ID, 'ctl04_txtInvoiceNumber_0') )
        ).send_keys( self._info.get('invoice number') )

        # Select Ship To company
        company_select = Select( self._browser.find_element_by_id('ctl04_SoldToDDL') )
        company_select.select_by_visible_text('Columbus City Schools')

        # Toggle to share claim
        self._browser.execute_script(
            'arguments[0].click();',
            self._wait.until(
                EC.element_to_be_clickable( (By.ID, 'ctl04_rblShare_0') )
            )
        )

        # Choose all the shared users
        shared_user_1_select = Select( self._browser.find_element_by_id('ctl04_DDLShareUser1') )
        shared_user_1_select.select_by_visible_text('Curtiss, Tim (tim.curtiss@cbts.net)')
        shared_user_2_select = Select( self._browser.find_element_by_id('ctl04_DDLShareUser2') )
        shared_user_2_select.select_by_visible_text('burns, chris (christopher.burns@cbts.net)')
        shared_user_3_select = Select( self._browser.find_element_by_id('ctl04_DDLShareUser3') )
        shared_user_3_select.select_by_visible_text('Rinehart, Kyle (kyle.rinehart@cbts.com)')

        # Click "Continue" button
        self._browser.execute_script(
            'arguments[0].click();',
            self._wait.until(
                EC.element_to_be_clickable( (By.ID, 'ctl04_btnNext') )
            )
        )

    def __add_product_number(self):
        # Select the correct product number
        self._wait.until(
            EC.presence_of_element_located( (By.ID, 'ctl04_dgSearchTerm') )
        ).send_keys( self._info.get('product number') )

        # To update the product number list to the correct one
        self._browser.execute_script(
            'arguments[0].click();',
            self._wait.until(
                EC.element_to_be_clickable( (By.ID, 'ctl04_Button1') )
            )
        )

        # Add the product number to the claim
        self._browser.execute_script(
            'arguments[0].click();',
            self._wait.until(
                EC.element_to_be_clickable( (By.ID, 'ctl04_dgCatalog_ctl03_Add2Claim') )
            )
        )

    def __add_total_devices(self):
        # Add the total number of devices to the claim
        search_box = self._wait.until(
            EC.presence_of_element_located( (By.ID, 'ctl04_rptCatalogsCart_ctl00_EditQty') )
        )
        search_box.clear() # The default value for this field is "1"
        search_box.send_keys( self._info.get('quantity') )

        # Click the "Update Claim" button
        self._browser.execute_script(
            'arguments[0].click();',
            self._wait.until(
                EC.element_to_be_clickable( (By.ID, 'ctl04_btnUpdateCart') )
            )
        )
        # Click the continue button
        self._browser.execute_script(
            'arguments[0].click();',
            self._wait.until(
                EC.element_to_be_clickable( (By.ID, 'ctl04_btnCheckout') )
            )
        )

    def __upload_invoice(self):
        # Upload the PDF of the invoice
        self._wait.until(
            EC.presence_of_element_located( (By.ID, 'ctl04_radAsyncFileUploadfile0') )
        ).send_keys( self._info.get('invoice path') )
        # Click the "Upload" button
        self._browser.execute_script(
            'arguments[0].click();',
            self._wait.until(
                EC.element_to_be_clickable( (By.ID, 'ctl04_radbtnAsyncFileUpload_input') )
            )
        )

    def __upload_serials(self):
        # Upload the XLSX with all the serials/product number
        self._wait.until(
            EC.presence_of_element_located( (By.ID, 'ctl04_FileInputSerial') )
        ).send_keys( self._info.get('serial path') )
        # Click the "Upload" button
        self._browser.execute_script(
            'arguments[0].click();',
            self._wait.until(
                EC.element_to_be_clickable( (By.ID, 'ctl04_btnUploadSerial') )
            )
        )

    def __check_for_errors(self):
        '''
        Makes sure that there are no errors with the submitted serial numbers and quantity.
        '''
        err_msg = (
            'One or more errors were found with the serial numbers / '
            'SAIDs provided. Please correct these errors and try again.'
        )

        try:
            WebDriverWait(self._browser, 5).until(
                EC.text_to_be_present_in_element(
                    (By.ID, 'ctl04_lblErrorMessage'), err_msg
                )
            )
            self._browser.quit()
            sg.popup_error(err_msg, title='Error')
        # No error messages appeared on page
        except TimeoutException:
            self.__complete_claim()

    def __complete_claim(self):
        # Click the "Complete Claim" button
        self._browser.execute_script(
            'arguments[0].click();',
            self._wait.until(
                EC.element_to_be_clickable( (By.ID, 'ctl04_btnCompleteClaim') )
            )
        )

        # To make sure claim was submitted, before closing the browser
        self._wait.until(
            EC.text_to_be_present_in_element(
                (By.ID, 'ctl04_lblStatus'), 'Pending - New'
            )
        )
        self._browser.quit()
        sg.popup('HP Blue Carpet claim has been successfully submitted!', title='Success')

    def create(self):
        self._log_into_hp_warranty_site()
        self.__go_to_new_claim_page()
        self.__fill_out_claim_setup()
        self.__add_product_number()
        self.__add_total_devices()
        self.__upload_invoice()
        self.__upload_serials()
        self.__check_for_errors()
